package cn.edu.nju.software.net;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

public class Connection {
	private static Connection instance = null;//Connection��Ψһʵ��
	private DataInputStream inputStream = null;
	private DataOutputStream outputStream = null;

	private Connection() {
		final String ip = "127.0.0.1";
		final int port = 4700;
		Socket socket = null;
		try {
			socket = new Socket(ip, port);
			outputStream = new DataOutputStream(new BufferedOutputStream(
					socket.getOutputStream()));
			inputStream = new DataInputStream(new BufferedInputStream(
					socket.getInputStream()));
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static Connection getInstance() {//Singleton ģʽ
		if (instance == null) {
			instance = new Connection();
		}
		return instance;
	}

	//�����½
	public LogType handleLog(String userName, String password) {
		try {
			this.outputStream.writeInt(1);
			this.outputStream.writeUTF(userName);
			this.outputStream.writeUTF(password);
			this.outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			switch (this.inputStream.readInt()) {
			case 1:
				return LogType.Administrator;
			case 2:
				return LogType.Student;
			case 3:
				return LogType.LogFail;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return LogType.LogFail;
	}

	//����������
	public boolean handleChangePassword(String userName,
			String origianlPassword, String newPassword) {
		try {
			this.outputStream.writeInt(2);
			this.outputStream.writeUTF(userName);
			this.outputStream.writeUTF(origianlPassword);
			this.outputStream.writeUTF(newPassword);
			this.outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			return this.inputStream.readBoolean();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	//������ʾ������Ϣ
	public StudentBean handlePersonalInformation(String userName) {
		try {
			outputStream.writeInt(3);
			outputStream.writeUTF(userName);
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		StudentBean student = new StudentBean();
		try {
			student.setId(inputStream.readUTF());
			student.setName(inputStream.readUTF());
			student.setGender(inputStream.readUTF());
			student.setInstitute(inputStream.readUTF());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return student;
	}

	//��ʾѧ��γ����
	public ArrayList<ArrayList<CourseBean>> handleCourseView(String userName) {
		try {
			outputStream.writeInt(4);
			outputStream.writeUTF(userName);
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		ArrayList<ArrayList<CourseBean>> allCourses = new ArrayList<ArrayList<CourseBean>>();
		ArrayList<CourseBean> unChosenCourses = new ArrayList<CourseBean>();
		ArrayList<CourseBean> chosenCourses = new ArrayList<CourseBean>();

		String cid = "";
		String cName = "";
		String cTeacher = "";
		int cGrade = 0;
		int cNumber = 0;
		String cPlace = "";
		String cInstitute = "";
		try {
			while (!(cid = inputStream.readUTF()).equals("unchosen_end")) {
				cName = inputStream.readUTF();
				cTeacher = inputStream.readUTF();
				cGrade = inputStream.readInt();
				cNumber = inputStream.readInt();
				cPlace = inputStream.readUTF();
				cInstitute = inputStream.readUTF();
				unChosenCourses.add(new CourseBean(cid, cName, cInstitute,
						cTeacher, cGrade, cNumber, cPlace, false));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			while (!(cid = inputStream.readUTF()).equals("course_end")) {
				cName = inputStream.readUTF();
				cTeacher = inputStream.readUTF();
				cGrade = inputStream.readInt();
				cNumber = inputStream.readInt();
				cPlace = inputStream.readUTF();
				cInstitute = inputStream.readUTF();
				chosenCourses.add(new CourseBean(cid, cName, cInstitute,
						cTeacher, cGrade, cNumber, cPlace, false));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		allCourses.add(unChosenCourses);
		allCourses.add(chosenCourses);
		return allCourses;
	}

	//����ѧ��ѡ��
	public boolean handleChooseCourse(String userName,
			ArrayList<CourseBean> chosenCourses) {
		try {
			outputStream.writeInt(5);
			outputStream.writeUTF(userName);
			for (CourseBean course : chosenCourses) {
				outputStream.writeUTF(course.getId());
				outputStream.writeUTF(course.getInstitute());
			}
			outputStream.writeUTF("����");
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			return inputStream.readBoolean();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;//����ѡ��ʧ�ܣ�����Ҫ�ָ���֮ǰ��״̬   Ҫ���ñ���
		}
	}

	//�������Ա�鿴�γ�
	public ArrayList<CourseBean> handleAdministratorCourseView() {
		try {
			outputStream.writeInt(6);
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		ArrayList<CourseBean> courses = new ArrayList<CourseBean>();
		String cid = "";
		String cName = "";
		String cTeacher = "";
		int cGrade = 0;
		int cNumber = 0;
		String cPlace = "";
		String cInstitute = "";
		boolean sharable = false;
		try {
			while (!(cid = inputStream.readUTF()).equals("�γ̽���")) {
				cName = inputStream.readUTF();
				cTeacher = inputStream.readUTF();
				cGrade = inputStream.readInt();
				cNumber = inputStream.readInt();
				cPlace = inputStream.readUTF();
				cInstitute = inputStream.readUTF();
				sharable = inputStream.readBoolean();
				courses.add(new CourseBean(cid, cName, cInstitute, cTeacher,
						cGrade, cNumber, cPlace, sharable));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return courses;
	}

	//�������Ա��ӿγ�
	public boolean handleAddCourse(ArrayList<CourseBean> courses) {
		try {
			outputStream.writeInt(7);
			for (CourseBean course : courses) {
				outputStream.writeUTF(course.getId());
				outputStream.writeUTF(course.getName());
				outputStream.writeUTF(course.getTeacher());
				outputStream.writeInt(course.getGrades());
				outputStream.writeInt(course.getNumber());
				outputStream.writeUTF(course.getPlace());
				outputStream.writeBoolean(course.getShared());
			}
			outputStream.writeUTF("�γ̽���");
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			return inputStream.readBoolean();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;//�����Ƿ�ɹ�
		}
	}

	//�������Աɾ��γ�
	public boolean handleDeleteCourse(ArrayList<CourseBean> courses) {
		try {
			outputStream.writeInt(8);
			for (CourseBean course : courses) {
				outputStream.writeUTF(course.getId());
			}
			outputStream.writeUTF("�γ̽���");
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			return inputStream.readBoolean();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	//�������Ա�鿴ѧ�����
	public ArrayList<StudentBean> handleAdministratorStudentView() {
		try {
			outputStream.writeInt(9);
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		ArrayList<StudentBean> students = new ArrayList<StudentBean>();
		String sid = "";
		String sName = "";
		String sGender = "";
		String sInstitute = "";
		try {
			while (!(sid = inputStream.readUTF()).equals("ѧ�����")) {
				sName = inputStream.readUTF();
				sGender = inputStream.readUTF();
				sInstitute = inputStream.readUTF();
				students.add(new StudentBean("", "", sid, sName, sGender,
						sInstitute));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return students;
	}

	//�������Ա���ѧ��
	public boolean handleAddStudent(ArrayList<StudentBean> students) {
		try {
			outputStream.writeInt(10);
			for (StudentBean student : students) {
				outputStream.writeUTF(student.getUserName());
				outputStream.writeUTF(student.getPassword());
				outputStream.writeUTF(student.getId());
				outputStream.writeUTF(student.getName());
				outputStream.writeUTF(student.getGender());
			}
			outputStream.writeUTF("ѧ�����");
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			return inputStream.readBoolean();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}
	
	//�������Աɾ��ѧ��
	public boolean handleDeleteStudent(ArrayList<StudentBean> students) {
		try {
			outputStream.writeInt(11);
			for (StudentBean student : students) {
				outputStream.writeUTF(student.getId());
			}
			outputStream.writeUTF("ѧ�����");
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			return inputStream.readBoolean();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	//�������Ա����γ�����
	public boolean handleShareCourse() {
		try {
			outputStream.writeInt(12);
			outputStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			return inputStream.readBoolean();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}
}
